#pragma once
// 使用C语言在Windows环境的控制台中模拟实现经典小游戏贪吃蛇

// 要实现的基础功能如下：
// 1.贪吃蛇地图绘制
// 2.蛇吃食物的功能（上、下、左、右方向键控制蛇的动作）
// 3.蛇撞墙死亡
// 4.蛇撞自身死亡
// 5.计算得分
// 6.蛇身加速、减速
// 7.暂停游戏

// 技术要点：
// C语言函数、枚举、结构体、动态内存管理、预处理指令、链表、Win32 API

#include <stdio.h>
#include <stdlib.h>
#include <locale.h>
#include <windows.h>
#include <stdbool.h>

#define WALL L'■'
#define BODY L'●'
#define FOOD L'❤'

// 蛇默认的起始坐标
#define POS_X 24
#define POS_Y 5

#define KEY_PRESS(VK) ( (GetAsyncKeyState(VK) & 0x1) ? 1 : 0 )

// 游戏状态
enum GAME_STATUS
{
	OK = 1, // 正常运行
	ESC, // 按了ESC键正常退出
	KILL_BY_WALL,
	KILL_BY_SELF
};

// 蛇行走的方向
enum DIRECTION
{
	UP,
	DOWN,
	LEFT,
	RIGHT
};

// 贪吃蛇蛇身节点
typedef struct SnakeNode
{
	int x;
	int y;
	struct SnakeNode* next;
}SnakeNode, *pSnakeNode;

// 贪吃蛇
typedef struct Snake
{
	pSnakeNode pSnake; // 维护整条蛇的指针,其实是指向蛇头的
	pSnakeNode pFood; // 指向食物的指针
	int Score; // 当前累积的分数
	int FoodWeight; // 一个食物的分数
	int SleepTime; // 蛇休眠的时间，休眠时间越短，速度越快
	enum GAME_STATUS status; // 游戏当前状态
	enum DIRECTION dir; // 蛇当前走的方向
	// ...
}Snake, *pSnake;

// 定位控制台的光标位置
void SetPos(int x, int y);

// 游戏开始前的准备环节
void GameStart(pSnake ps);

// 打印欢迎界面
void WelcomeToGame();

// 绘制地图
void CreateMap();

// 初始化贪吃蛇
void InitSnake(pSnake ps);

// 创建食物
void CreateFood(pSnake ps);

// 游戏运行的整个逻辑
void GameRun(pSnake ps);

// 打印帮助信息
void PrintHelpInfo();

// 判断蛇头下一步要走的位置处是不是食物
int NextIsFood(pSnake ps, pSnakeNode pNext);

// 下一步要走的位置处就是食物
void EatFood(pSnake ps, pSnakeNode pNext);

// 下一步要走的位置不是食物
void NotEatFood(pSnake ps, pSnakeNode pNext);

// 检测是否撞墙
void KillByWall(pSnake ps);

// 检测是否撞自己
void KillBySelf(pSnake ps);

// 游戏结束的资源释放
void GameEnd(pSnake ps);
